package cn.daniellee.plugin.wc.command;

import cn.daniellee.plugin.wc.WorldChecker;
import cn.daniellee.plugin.wc.model.Confirm;
import cn.daniellee.plugin.wc.model.WorldNeedCheck;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.milkbowl.vault.economy.Economy;
import org.apache.commons.lang3.StringUtils;
import org.black_ixx.playerpoints.PlayerPoints;
import org.black_ixx.playerpoints.PlayerPointsAPI;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import java.util.List;
import java.util.stream.Collectors;

public class CheckerCommand implements CommandExecutor {
	@Override
	public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) {
		if (strings.length == 0 || strings[0].equalsIgnoreCase("help")) {
			sendHelp(commandSender);
		} else if (strings[0].equalsIgnoreCase("confirm") && commandSender instanceof Player) {
			Player player = (Player) commandSender;
			Confirm confirm = WorldChecker.getInstance().getConfirmMap().get(player.getName());
			if (confirm != null) {
				boolean success = false;
				if ("vault".equalsIgnoreCase(confirm.getCostType())) {
					Economy economy = Bukkit.getServicesManager().getRegistration(Economy.class).getProvider();
					success = economy.withdrawPlayer(player, confirm.getJoinCost()).transactionSuccess();
				} else {
					PlayerPointsAPI playerPointsAPI = ((PlayerPoints) Bukkit.getPluginManager().getPlugin("PlayerPoints")).getAPI();
					success = playerPointsAPI.take(player.getName(), (int) confirm.getJoinCost());
				}
				if (success) {
					confirm.setConfirm(true);
					player.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.payment-enter", "&eSuccessful payment to enter the world fee &b{cost} &e{type}.").replace("{cost}", Double.toString(confirm.getJoinCost())).replace("{type}", WorldChecker.getInstance().getConfig().getString("message.type." + confirm.getCostType(), confirm.getCostType()))).replace("&", "§"));
					player.teleport(confirm.getTarget());
				} else player.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.payment-failed", "&ePayment failed, your balance is insufficient.")).replace("&", "§"));
			}
		} else if (commandSender.isOp()) {
			if ("reload".equalsIgnoreCase(strings[0])) {
				WorldChecker.getInstance().reloadConfig();
				WorldChecker.getInstance().loadConfig();
				commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("reload-success", "&eConfiguration reload successfully.")).replace("&", "§"));
			} else if ("list".equalsIgnoreCase(strings[0])) {
				List<String> worldNames = WorldChecker.getInstance().getWorldNeedChecks().stream().map(WorldNeedCheck::getWorldName).collect(Collectors.toList());
				commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.check-worlds", "&eThe world that currently needs to check in has: &r") + StringUtils.join(worldNames, ", ")).replace("&", "§"));
			} else if ("add".equalsIgnoreCase(strings[0]) && strings.length > 1) {
				if (Bukkit.getWorld(strings[1]) != null) {
					if (WorldChecker.getInstance().getWorldNeedCheckByWorldName(strings[1]) == null) {
						WorldChecker.getInstance().getConfig().set("world-need-check." + strings[1] + ".permission", "worldchecker." + strings[1]);
						WorldChecker.getInstance().getConfig().set("world-need-check." + strings[1] + ".allow-paid", true);
						WorldChecker.getInstance().getConfig().set("world-need-check." + strings[1] + ".cost-type", "vault");
						WorldChecker.getInstance().getConfig().set("world-need-check." + strings[1] + ".cost-per-join", 1000);
						WorldChecker.getInstance().saveConfig();
						WorldNeedCheck worldNeedCheck = new WorldNeedCheck();
						worldNeedCheck.setWorldName(strings[1]);
						worldNeedCheck.setPermission("worldchecker." + strings[1]);
						worldNeedCheck.setAllowPaid(true);
						worldNeedCheck.setCostType("vault");
						worldNeedCheck.setCostPerJoin(1000);
						WorldChecker.getInstance().getWorldNeedChecks().add(worldNeedCheck);
						commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.add-success", "&eAdd world checker success.")).replace("&", "§"));
						showWorldInfo(commandSender, worldNeedCheck);
					} else commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.already-set", "&eThe target world is already in the set.")).replace("&", "§"));
				} else commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.invalid-world", "&eInvalid world name.")).replace("&", "§"));
			} else if ("del".equalsIgnoreCase(strings[0]) && strings.length > 1) {
				WorldNeedCheck worldNeedCheck = WorldChecker.getInstance().getWorldNeedCheckByWorldName(strings[1]);
				if (worldNeedCheck != null) {
					WorldChecker.getInstance().getConfig().set("world-need-check." + worldNeedCheck.getWorldName(), null);
					WorldChecker.getInstance().saveConfig();
					WorldChecker.getInstance().getWorldNeedChecks().remove(worldNeedCheck);
					commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.del-success", "&eDel world checker success.")).replace("&", "§"));
				} else commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.not-check", "&eThe target world is not in the settings.")).replace("&", "§"));
			} else if ("perm".equalsIgnoreCase(strings[0]) && strings.length > 2) {
				WorldNeedCheck worldNeedCheck = WorldChecker.getInstance().getWorldNeedCheckByWorldName(strings[1]);
				if (worldNeedCheck != null) {
					WorldChecker.getInstance().getConfig().set("world-need-check." + worldNeedCheck.getWorldName() + ".permission", strings[2]);
					WorldChecker.getInstance().saveConfig();
					worldNeedCheck.setPermission(strings[2]);
					commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.set-success", "&eThe configuration was successfully modified.")).replace("&", "§"));
					showWorldInfo(commandSender, worldNeedCheck);
				} else commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.not-check", "&eThe target world is not in the settings.")).replace("&", "§"));
			} else if ("paid".equalsIgnoreCase(strings[0]) && strings.length > 2) {
				WorldNeedCheck worldNeedCheck = WorldChecker.getInstance().getWorldNeedCheckByWorldName(strings[1]);
				if (worldNeedCheck != null) {
					boolean allowPaid = Boolean.valueOf(strings[2]);
					WorldChecker.getInstance().getConfig().set("world-need-check." + worldNeedCheck.getWorldName() + ".allow-paid", allowPaid);
					WorldChecker.getInstance().saveConfig();
					worldNeedCheck.setAllowPaid(allowPaid);
					commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.set-success", "&eThe configuration was successfully modified.")).replace("&", "§"));
					showWorldInfo(commandSender, worldNeedCheck);
				} else commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.not-check", "&eThe target world is not in the settings.")).replace("&", "§"));
			} else if ("type".equalsIgnoreCase(strings[0]) && strings.length > 2) {
				WorldNeedCheck worldNeedCheck = WorldChecker.getInstance().getWorldNeedCheckByWorldName(strings[1]);
				if (worldNeedCheck != null) {
					if ("vault".equalsIgnoreCase(strings[2]) || "points".equalsIgnoreCase(strings[2])) {
						WorldChecker.getInstance().getConfig().set("world-need-check." + worldNeedCheck.getWorldName() + ".cost-type", strings[2]);
						WorldChecker.getInstance().saveConfig();
						worldNeedCheck.setCostType(strings[2]);
						commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.set-success", "&eThe configuration was successfully modified.")).replace("&", "§"));
						showWorldInfo(commandSender, worldNeedCheck);
					} else commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.invalid-parm", "&eInvalid parameter.")).replace("&", "§"));
				} else commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.not-check", "&eThe target world is not in the settings.")).replace("&", "§"));
			} else if ("cost".equalsIgnoreCase(strings[0]) && strings.length > 2) {
				WorldNeedCheck worldNeedCheck = WorldChecker.getInstance().getWorldNeedCheckByWorldName(strings[1]);
				if (worldNeedCheck != null) {
					double costPerJoin = Double.valueOf(strings[2]);
					WorldChecker.getInstance().getConfig().set("world-need-check." + worldNeedCheck.getWorldName() + ".cost-per-join", costPerJoin);
					WorldChecker.getInstance().saveConfig();
					worldNeedCheck.setCostPerJoin(costPerJoin);
					commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.set-success", "&eThe configuration was successfully modified.")).replace("&", "§"));
					showWorldInfo(commandSender, worldNeedCheck);
				} else commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.not-check", "&eThe target world is not in the settings.")).replace("&", "§"));
			} else sendHelp(commandSender);
		} else commandSender.sendMessage((WorldChecker.getInstance().getPrefix() + WorldChecker.getInstance().getConfig().getString("message.only-op", "&cOnly OP can do this.")).replace("&", "§"));
		return true;
	}

	private void showWorldInfo(CommandSender commandSender, WorldNeedCheck worldNeedCheck) {
		List<String> showInfo = WorldChecker.getInstance().getConfig().getStringList("message.show-info");
		if (showInfo != null && !showInfo.isEmpty()) {
			showInfo.forEach(item -> commandSender.sendMessage(item.replace("{world-name}", worldNeedCheck.getWorldName()).replace("{permission}", worldNeedCheck.getPermission()).replace("{allow-paid}", Boolean.toString(worldNeedCheck.isAllowPaid()).toUpperCase()).replace("{cost-type}", worldNeedCheck.getCostType().toUpperCase()).replace("{cost-per-join}", Double.toString(worldNeedCheck.getCostPerJoin())).replace("&", "§")));
		}
	}

	private void sendHelp(CommandSender commandSender) {
		commandSender.sendMessage(("&m&6---&m&a--------&3 : " + WorldChecker.getInstance().getConfig().getString("prompt-prefix", "&6WorldChecker") + "&3 : &m&a--------&m&6---").replace("&", "§"));

		String spawnText =  WorldChecker.getInstance().getConfig().getString("help.list-help", "&eList all need check worlds.").replace("&", "§");
		TextComponent spawnHelp = new TextComponent("/wc list  " + spawnText);
		spawnHelp.setColor(ChatColor.GRAY);
		spawnHelp.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/wc list"));
		spawnHelp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(spawnText).color(ChatColor.BLUE).create()));
		commandSender.spigot().sendMessage(spawnHelp);

		String addText = WorldChecker.getInstance().getConfig().getString("help.add-help", "&eAdd world checker.").replace("&", "§");
		TextComponent addHelp = new TextComponent("/wc add <world>  " + addText);
		addHelp.setColor(ChatColor.GRAY);
		addHelp.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/wc add "));
		addHelp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(addText).color(ChatColor.BLUE).create()));
		commandSender.spigot().sendMessage(addHelp);

		String delText = WorldChecker.getInstance().getConfig().getString("help.del-help", "&eRemove world checker.").replace("&", "§");
		TextComponent delHelp = new TextComponent("/wc del <world>  " + delText);
		delHelp.setColor(ChatColor.GRAY);
		delHelp.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/wc del "));
		delHelp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(delText).color(ChatColor.BLUE).create()));
		commandSender.spigot().sendMessage(delHelp);

		String permText = WorldChecker.getInstance().getConfig().getString("help.perm-help", "&eSet permissions to allow free access to the target world.").replace("&", "§");
		TextComponent permHelp = new TextComponent("/wc perm <world> <permission>  " + permText);
		permHelp.setColor(ChatColor.GRAY);
		permHelp.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/wc perm "));
		permHelp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(permText).color(ChatColor.BLUE).create()));
		commandSender.spigot().sendMessage(permHelp);

		String paidText = WorldChecker.getInstance().getConfig().getString("help.paid-help", "&eSet whether to allow unauthorized access to pay.").replace("&", "§");
		TextComponent paidHelp = new TextComponent("/wc paid <world> <true/false>  " + paidText);
		paidHelp.setColor(ChatColor.GRAY);
		paidHelp.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/wc paid "));
		paidHelp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(paidText).color(ChatColor.BLUE).create()));
		commandSender.spigot().sendMessage(paidHelp);

		String typeText = WorldChecker.getInstance().getConfig().getString("help.type-help", "&eSet the type of fee entry without permission.").replace("&", "§");
		TextComponent typeHelp = new TextComponent("/wc type <world> <vault/points>  " + typeText);
		typeHelp.setColor(ChatColor.GRAY);
		typeHelp.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/wc type "));
		typeHelp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(typeText).color(ChatColor.BLUE).create()));
		commandSender.spigot().sendMessage(typeHelp);

		String costText = WorldChecker.getInstance().getConfig().getString("help.cost-help", "&eSet the amount of entry fee for those who do not have permission.").replace("&", "§");
		TextComponent costHelp = new TextComponent("/wc cost <world> <number>  " + costText);
		costHelp.setColor(ChatColor.GRAY);
		costHelp.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/wc cost "));
		costHelp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(costText).color(ChatColor.BLUE).create()));
		commandSender.spigot().sendMessage(costHelp);

		String reloadText = WorldChecker.getInstance().getConfig().getString("help.reload-help", "Reload configuration.").replace("&", "§");
		TextComponent reloadHelp = new TextComponent("/wc reload  " + reloadText);
		reloadHelp.setColor(ChatColor.GRAY);
		reloadHelp.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/wc reload"));
		reloadHelp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(reloadText).color(ChatColor.BLUE).create()));
		commandSender.spigot().sendMessage(reloadHelp);
	}

}
